import React from "react";
import { PlusOutlined } from "@ant-design/icons";
import { Button, Input } from "antd";
import AddItem from "./addItem";
import { useCallback, useState } from "react";
import { uid } from "@/utils";
import { useEffect } from "react";
import { omit } from "lodash-es";
export interface DynamicListProps<T> {
  component?: React.FC<any>;
  value?: T;

  onChange?: (data: T[]) => void;
  childrenComponent?: ({
    item,
    key,
    index,
    value,
    onDelete,
    onChangeItem,
  }: {
    onDelete?: (index: number, key: string) => void;
    key?: string;
    value?: T;
    index?: number;
    onChangeItem: (value: T, key?: string) => void;
    item?: DynamicListItemType;
  }) => React.ReactNode;
}
export type DynamicListItemType = {
  key: string;
};

function DynamicList<T>(props: DynamicListProps<T>) {
  const { value, childrenComponent, component: Component, onChange } = props;
  const [list, setList] = useState<DynamicListItemType[]>([]);
  const [data, setData] = useState<Record<string, T>>({});
  const onAdd = useCallback(() => {
    setList((oldList) => {
      return [...oldList, { key: uid() }];
    });
  }, []);
  useEffect(() => {
    if (Array.isArray(value)) {
      let map = {};
      const items = value?.map((item) => {
        const key = item?.key || uid();
        map[key] = item;
        return { key };
      });
      setList(items);
      setData(map);
    }
  }, [value]);
  const onChangeItem = useCallback(
    (value: T, key: string, index?: number) => {
      setData((oldData) => {
        return { ...oldData, [key]: value };
      });
      onChange?.(Object.values({ ...data, [key]: value }));
    },
    [data]
  );
  const onDelete = useCallback(
    (index: number, key: string) => {
      const _list = [...list];
      _list.splice(index, 1);
      setList(_list);
      const _data = omit(data, [key]);
      setData(_data);
      onChange?.(Object.values(_data));
    },
    [list, data]
  );
  const view = (
    <>
      {list?.map((item: DynamicListItemType, i: number) => (
        <AddItem>
          {childrenComponent?.({
            item,
            value: data?.[item?.key],
            key: item?.key,
            index: i,
            onDelete: () => onDelete(i, item?.key),
            onChangeItem: (value: T, key?: string) =>
              onChangeItem(value, key || item?.key, i),
          })}
        </AddItem>
      ))}
      <Button
        type="primary"
        style={{ width: "100%", marginTop: 12 }}
        onClick={onAdd}
        icon={<PlusOutlined />}
      >
        新增
      </Button>
    </>
  );
  if (Component) {
    return <Component onChange={onChange}>{view}</Component>;
  }
  return <div className="dynamic-list">{view}</div>;
}
export default DynamicList;
